#!/bin/bash

# =============================================================================
# macOS Release版本完整自动化构建脚本
# LimeReader macOS App Bundle Builder
# 版本: 1.0
# 创建日期: 2025-10-13
# =============================================================================

set -e  # 遇到错误立即退出

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color

# 配置变量
PROJECT_ROOT=$(pwd)
BUILD_DIR="build"
QT_PATH="/opt/homebrew/opt/qt6"
HOMEBREW_LIB="/opt/homebrew/lib"
APP_NAME="LimeReader.app"
CHINESE_APP_NAME="影谷长图处理大师.app"
BUNDLE_ID="com.limereader.app"
VERSION="2.7.2"
PKG_NAME="LimeReader_v${VERSION}_macOS.pkg"
DIST_DIR="dist"

# 日志函数
log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

log_step() {
    echo -e "${PURPLE}[STEP]${NC} $1"
}

# 检查依赖函数
check_dependencies() {
    log_step "检查构建依赖..."

    # 检查Qt安装
    if [ ! -d "$QT_PATH" ]; then
        log_error "Qt未找到，路径: $QT_PATH"
        log_info "请运行: brew install qt@6"
        exit 1
    fi

    # 检查Poppler安装
    if [ ! -d "/opt/homebrew/Cellar/poppler" ]; then
        log_error "Poppler未找到"
        log_info "请运行: brew install poppler"
        exit 1
    fi

    # 检查macdeployqt
    if [ ! -f "$QT_PATH/bin/macdeployqt" ]; then
        log_error "macdeployqt未找到"
        exit 1
    fi

    # 检查cmake
    if ! command -v cmake &> /dev/null; then
        log_error "cmake未找到"
        log_info "请运行: brew install cmake"
        exit 1
    fi

    log_success "所有依赖检查通过"
}

# 清理旧文件
cleanup_old_builds() {
    log_step "清理旧的构建文件..."

    # 清理项目中的所有.app文件
    find . -name "*.app" -type d -exec rm -rf {} + 2>/dev/null || true

    # 完全清理构建目录（跳过权限问题）
    if [ -d "$BUILD_DIR" ]; then
        log_info "检测到旧的构建目录，尝试清理..."

        # 尝试删除，如果失败则移动到临时目录
        if rm -rf "$BUILD_DIR" 2>/dev/null; then
            log_info "已删除旧的构建目录"
        else
            local temp_backup="${BUILD_DIR}_backup_$(date +%s)"
            mv "$BUILD_DIR" "$temp_backup" 2>/dev/null || {
                log_warning "无法清理旧的构建目录，将在现有目录中构建"
            }
        fi
    fi

    # 创建新的构建目录
    mkdir -p "$BUILD_DIR"
    log_success "构建环境已清理"
}

# CMake配置
configure_cmake() {
    log_step "配置CMake..."
    cd "$BUILD_DIR"

    cmake -DCMAKE_BUILD_TYPE=Release \
          -DCMAKE_PREFIX_PATH="$QT_PATH" \
          ..

    if [ $? -eq 0 ]; then
        log_success "CMake配置完成"
    else
        log_error "CMake配置失败"
        exit 1
    fi
}

# 执行构建
build_project() {
    log_step "执行并行构建..."

    cmake --build . --config Release --parallel

    if [ $? -eq 0 ]; then
        log_success "项目构建完成"
    else
        log_error "项目构建失败"
        exit 1
    fi
}

# 部署Qt依赖
deploy_qt_dependencies() {
    log_step "部署Qt依赖和插件..."

    cmake --build . --target deploy_mac

    if [ $? -eq 0 ]; then
        log_success "Qt依赖部署完成"
    else
        log_warning "Qt依赖部署可能有问题，继续执行..."
    fi
}

# 添加缺失的关键依赖
add_missing_dependencies() {
    log_step "添加缺失的关键依赖..."

    local app_path="bin/$APP_NAME"
    local frameworks_path="$app_path/Contents/Frameworks"

    # 添加QtDBus框架
    log_info "复制QtDBus.framework..."
    if cp -r "$QT_PATH/lib/QtDBus.framework" "$frameworks_path/"; then
        log_success "QtDBus.framework 添加成功"
    else
        log_error "QtDBus.framework 添加失败"
        exit 1
    fi

    # 添加libpoppler.153.dylib
    log_info "复制libpoppler.153.dylib..."
    if cp "$HOMEBREW_LIB/libpoppler.153.dylib" "$frameworks_path/"; then
        log_success "libpoppler.153.dylib 添加成功"
    else
        log_error "libpoppler.153.dylib 添加失败"
        exit 1
    fi
}

# 修复依赖路径
fix_dependency_paths() {
    log_step "修复依赖路径..."

    local frameworks_path="bin/$APP_NAME/Contents/Frameworks"
    local poppler_cpp="$frameworks_path/libpoppler-cpp.2.dylib"

    if [ -f "$poppler_cpp" ]; then
        install_name_tool -change "@rpath/libpoppler.153.dylib" \
                          "@executable_path/../Frameworks/libpoppler.153.dylib" \
                          "$poppler_cpp"
        log_success "libpoppler-cpp依赖路径已修复"
    else
        log_warning "未找到libpoppler-cpp.2.dylib，跳过路径修复"
    fi
}

# 清理签名冲突文件
cleanup_signing_conflicts() {
    log_step "清理可能导致签名冲突的文件..."

    local app_path="bin/$APP_NAME"

    # 删除旧的签名信息
    rm -rf "$app_path/Contents/_CodeSignature" 2>/dev/null || true

    # 删除icons目录（可能导致签名冲突）
    rm -rf "$app_path/Contents/MacOS/icons/" 2>/dev/null || true

    log_success "签名冲突文件已清理"
}

# 代码签名
code_sign_app() {
    log_step "执行代码签名..."

    local app_path="bin/$APP_NAME"
    local frameworks_path="$app_path/Contents/Frameworks"
    local plugins_path="$app_path/Contents/PlugIns"

    # 签名所有框架
    log_info "签名Qt框架..."
    find "$frameworks_path" -name "*.framework" -exec codesign -f -s - {} \; 2>/dev/null || true

    # 签名所有动态库
    log_info "签名动态库..."
    find "$frameworks_path" -name "*.dylib" -exec codesign -f -s - {} \; 2>/dev/null || true

    # 签名所有插件
    log_info "签名插件..."
    find "$plugins_path" -name "*.dylib" -exec codesign -f -s - {} \; 2>/dev/null || true

    # 签名主可执行文件
    log_info "签名主可执行文件..."
    codesign -f -s - "$app_path/Contents/MacOS/LimeReader"

    # 签名整个应用包
    log_info "签名应用包..."
    codesign -f -s - "$app_path"

    log_success "代码签名完成"
}

# 验证构建结果
verify_build() {
    log_step "验证构建结果..."

    local app_path="bin/$APP_NAME"

    # 检查应用包结构
    if [ -d "$app_path" ]; then
        log_success "应用包已生成: $app_path"
    else
        log_error "应用包未找到"
        exit 1
    fi

    # 检查关键文件
    local executable="$app_path/Contents/MacOS/LimeReader"
    if [ -f "$executable" ]; then
        log_success "可执行文件存在"
    else
        log_error "可执行文件未找到"
        exit 1
    fi

    # 检查图标
    local icon="$app_path/Contents/Resources/app.icns"
    if [ -f "$icon" ]; then
        log_success "应用图标存在"
    else
        log_warning "应用图标未找到"
    fi

    # 检查关键框架
    local frameworks_path="$app_path/Contents/Frameworks"
    local qt_core="$frameworks_path/QtCore.framework"
    local qt_dbus="$frameworks_path/QtDBus.framework"
    local poppler="$frameworks_path/libpoppler.153.dylib"

    if [ -d "$qt_core" ]; then
        log_success "QtCore框架存在"
    else
        log_warning "QtCore框架未找到"
    fi

    if [ -d "$qt_dbus" ]; then
        log_success "QtDBus框架存在"
    else
        log_warning "QtDBus框架未找到"
    fi

    if [ -f "$poppler" ]; then
        log_success "Poppler库存在"
    else
        log_warning "Poppler库未找到"
    fi

    # 显示依赖信息
    log_info "主要依赖检查:"
    otool -L "$executable" | head -10
}

# 尝试启动应用测试
test_application() {
    log_step "测试应用启动..."

    local app_path="bin/$APP_NAME"

    # 尝试打开应用
    open "$app_path" &

    # 等待3秒
    sleep 3

    # 检查进程
    if pgrep -f "LimeReader" > /dev/null; then
        log_success "应用启动成功！"
        log_info "进程信息:"
        ps aux | grep LimeReader | grep -v grep
    else
        log_warning "未检测到运行中的应用进程"
        log_info "请手动检查应用是否正常启动"
    fi
}

# 生成构建报告
generate_build_report() {
    log_step "生成构建报告..."

    local report_file="build_report_$(date +%Y%m%d_%H%M%S).txt"
    local app_path="bin/$APP_NAME"

    {
        echo "========================================"
        echo "LimeReader macOS构建报告"
        echo "构建时间: $(date)"
        echo "========================================"
        echo
        echo "构建配置:"
        echo "- 项目版本: $VERSION"
        echo "- 构建类型: Release"
        echo "- Qt路径: $QT_PATH"
        echo "- 应用包位置: $PWD/$app_path"
        echo
        echo "应用包信息:"
        ls -la "$app_path/Contents/"
        echo
        echo "框架清单:"
        ls -la "$app_path/Contents/Frameworks/" | head -20
        echo
        echo "依赖信息:"
        otool -L "$app_path/Contents/MacOS/LimeReader" | head -15
        echo
        echo "构建完成!"
        echo "========================================"
    } > "$report_file"

    log_success "构建报告已生成: $report_file"
}

# 主构建流程
main() {
    echo -e "${CYAN}"
    echo "========================================"
    echo "  LimeReader macOS Release 自动化构建  "
    echo "========================================"
    echo -e "${NC}"

    # 记录开始时间
    local start_time=$(date +%s)

    # 执行构建步骤
    check_dependencies

    # 检查是否已有可用的应用
    local current_dir=$(pwd)
    local app_path="$current_dir/$BUILD_DIR/bin/$APP_NAME"
    if [ -f "$app_path/Contents/MacOS/LimeReader" ]; then
        log_info "检测到已构建的应用，跳过构建步骤"
        # 清理临时文件（使用绝对路径）
        rm -f "$app_path/Contents/MacOS/config.json" "$app_path/Contents/MacOS/debug.log"
        rm -rf "$app_path/Contents/MacOS/cache/"
        log_success "已清理临时文件"
    else
        cleanup_old_builds
        configure_cmake
        build_project
        deploy_qt_dependencies
        add_missing_dependencies
        fix_dependency_paths
        cleanup_signing_conflicts
        code_sign_app
    fi

    verify_build
    test_application
    create_pkg_package
    generate_build_report

    # 计算构建时间
    local end_time=$(date +%s)
    local duration=$((end_time - start_time))

    echo -e "${GREEN}"
    echo "========================================"
    echo "        构建成功完成！ 🎉"
    echo "========================================"
    echo -e "${NC}"
    log_success "总构建时间: ${duration}秒"
    log_success "应用包位置: $PWD/$BUILD_DIR/bin/$APP_NAME"
    log_success "PKG安装包: $PWD/$DIST_DIR/$PKG_NAME"
    log_info "安装后的应用名称: $CHINESE_APP_NAME"
    echo
    echo -e "${CYAN}📦 分发信息:${NC}"
    echo -e "${YELLOW}  应用包 (开发): $PWD/$BUILD_DIR/bin/$APP_NAME${NC}"
    echo -e "${YELLOW}  安装包 (用户): $PWD/$DIST_DIR/$PKG_NAME${NC}"
    echo
    echo -e "${CYAN}🚀 使用方法:${NC}"
    echo -e "${YELLOW}  测试应用: open $PWD/$BUILD_DIR/bin/$APP_NAME${NC}"
    echo -e "${YELLOW}  安装PKG: open $PWD/$DIST_DIR/$PKG_NAME${NC}"
    echo
}

# 错误处理
handle_error() {
    local exit_code=$?
    log_error "构建失败，错误代码: $exit_code"
    log_info "请检查上面的错误信息"
    exit $exit_code
}

# 创建PKG安装包（使用可靠系统）
create_pkg_package() {
    log_step "创建PKG安装包..."

    # 调用可靠的PKG构建脚本
    if [ -f "./create_reliable_pkg.sh" ]; then
        log_info "使用可靠的PKG构建系统..."
        ./create_reliable_pkg.sh
    else
        log_error "未找到可靠的PKG构建脚本"
        return 1
    fi
}

# 设置错误处理
trap handle_error ERR

# 执行主流程
main "$@"